home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / dev / misc / AmigaSDLsrc.lha / amisrc / SDL_blit_A.c < prev    next >
C/C++ Source or Header  |  2001-04-29  |  16KB  |  634 lines

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
  4.  
  5.     This library is free software; you can redistribute it and/or
  6.     modify it under the terms of the GNU Library General Public
  7.     License as published by the Free Software Foundation; either
  8.     version 2 of the License, or (at your option) any later version.
  9.  
  10.     This library is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.     Library General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Library General Public
  16.     License along with this library; if not, write to the Free
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.     Sam Lantinga
  20.     slouken@devolution.com
  21. */
  22.  
  23. #ifdef SAVE_RCSID
  24. static char rcsid =
  25.  "@(#) $Id: SDL_blit_A.c,v 1.3.2.9 2001/03/04 17:36:19 hercules Exp $";
  26. #endif
  27.  
  28. #include <stdio.h>
  29.  
  30. #include "SDL_types.h"
  31. #include "SDL_video.h"
  32. #include "SDL_blit.h"
  33.  
  34. /* Functions to perform alpha blended blitting */
  35.  
  36. /* N->1 blending with per-surface alpha */
  37. static void BlitNto1SurfaceAlpha(SDL_BlitInfo *info)
  38. {
  39.     int width = info->d_width;
  40.     int height = info->d_height;
  41.     Uint8 *src = info->s_pixels;
  42.     int srcskip = info->s_skip;
  43.     Uint8 *dst = info->d_pixels;
  44.     int dstskip = info->d_skip;
  45.     Uint8 *palmap = info->table;
  46.     SDL_PixelFormat *srcfmt = info->src;
  47.     SDL_PixelFormat *dstfmt = info->dst;
  48.     int srcbpp = srcfmt->BytesPerPixel;
  49.  
  50.     const unsigned A = srcfmt->alpha;
  51.  
  52.     while ( height-- ) {
  53.         DUFFS_LOOP4(
  54.         {
  55.         Uint32 pixel;
  56.         unsigned sR;
  57.         unsigned sG;
  58.         unsigned sB;
  59.         unsigned dR;
  60.         unsigned dG;
  61.         unsigned dB;
  62.         DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB);
  63.         dR = dstfmt->palette->colors[*dst].r;
  64.         dG = dstfmt->palette->colors[*dst].g;
  65.         dB = dstfmt->palette->colors[*dst].b;
  66.         ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  67.         dR &= 0xff;
  68.         dG &= 0xff;
  69.         dB &= 0xff;
  70.         /* Pack RGB into 8bit pixel */
  71.         if ( palmap == NULL ) {
  72.             *dst =((dR>>5)<<(3+2))|
  73.               ((dG>>5)<<(2))|
  74.               ((dB>>6)<<(0));
  75.         } else {
  76.             *dst = palmap[((dR>>5)<<(3+2))|
  77.                   ((dG>>5)<<(2))  |
  78.                   ((dB>>6)<<(0))];
  79.         }
  80.         dst++;
  81.         src += srcbpp;
  82.         },
  83.         width);
  84.         src += srcskip;
  85.         dst += dstskip;
  86.     }
  87. }
  88.  
  89. /* N->1 blending with pixel alpha */
  90. static void BlitNto1PixelAlpha(SDL_BlitInfo *info)
  91. {
  92.     int width = info->d_width;
  93.     int height = info->d_height;
  94.     Uint8 *src = info->s_pixels;
  95.     int srcskip = info->s_skip;
  96.     Uint8 *dst = info->d_pixels;
  97.     int dstskip = info->d_skip;
  98.     Uint8 *palmap = info->table;
  99.     SDL_PixelFormat *srcfmt = info->src;
  100.     SDL_PixelFormat *dstfmt = info->dst;
  101.     int srcbpp = srcfmt->BytesPerPixel;
  102.  
  103.     /* FIXME: fix alpha bit field expansion here too? */
  104.     while ( height-- ) {
  105.         DUFFS_LOOP4(
  106.         {
  107.         Uint32 pixel;
  108.         unsigned sR;
  109.         unsigned sG;
  110.         unsigned sB;
  111.         unsigned sA;
  112.         unsigned dR;
  113.         unsigned dG;
  114.         unsigned dB;
  115.         DISEMBLE_RGBA(src,srcbpp,srcfmt,pixel,sR,sG,sB,sA);
  116.         dR = dstfmt->palette->colors[*dst].r;
  117.         dG = dstfmt->palette->colors[*dst].g;
  118.         dB = dstfmt->palette->colors[*dst].b;
  119.         ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
  120.         dR &= 0xff;
  121.         dG &= 0xff;
  122.         dB &= 0xff;
  123.         /* Pack RGB into 8bit pixel */
  124.         if ( palmap == NULL ) {
  125.             *dst =((dR>>5)<<(3+2))|
  126.               ((dG>>5)<<(2))|
  127.               ((dB>>6)<<(0));
  128.         } else {
  129.             *dst = palmap[((dR>>5)<<(3+2))|
  130.                   ((dG>>5)<<(2))  |
  131.                   ((dB>>6)<<(0))  ];
  132.         }
  133.         dst++;
  134.         src += srcbpp;
  135.         },
  136.         width);
  137.         src += srcskip;
  138.         dst += dstskip;
  139.     }
  140. }
  141.  
  142. /* colorkeyed N->1 blending with per-surface alpha */
  143. static void BlitNto1SurfaceAlphaKey(SDL_BlitInfo *info)
  144. {
  145.     int width = info->d_width;
  146.     int height = info->d_height;
  147.     Uint8 *src = info->s_pixels;
  148.     int srcskip = info->s_skip;
  149.     Uint8 *dst = info->d_pixels;
  150.     int dstskip = info->d_skip;
  151.     Uint8 *palmap = info->table;
  152.     SDL_PixelFormat *srcfmt = info->src;
  153.     SDL_PixelFormat *dstfmt = info->dst;
  154.     int srcbpp = srcfmt->BytesPerPixel;
  155.     Uint32 ckey = srcfmt->colorkey;
  156.  
  157.     const int A = srcfmt->alpha;
  158.  
  159.     while ( height-- ) {
  160.         DUFFS_LOOP(
  161.         {
  162.         Uint32 pixel;
  163.         unsigned sR;
  164.         unsigned sG;
  165.         unsigned sB;
  166.         unsigned dR;
  167.         unsigned dG;
  168.         unsigned dB;
  169.         DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB);
  170.         if ( pixel != ckey ) {
  171.             dR = dstfmt->palette->colors[*dst].r;
  172.             dG = dstfmt->palette->colors[*dst].g;
  173.             dB = dstfmt->palette->colors[*dst].b;
  174.             ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  175.             dR &= 0xff;
  176.             dG &= 0xff;
  177.             dB &= 0xff;
  178.             /* Pack RGB into 8bit pixel */
  179.             if ( palmap == NULL ) {
  180.             *dst =((dR>>5)<<(3+2))|
  181.                   ((dG>>5)<<(2)) |
  182.                   ((dB>>6)<<(0));
  183.             } else {
  184.             *dst = palmap[((dR>>5)<<(3+2))|
  185.                       ((dG>>5)<<(2))  |
  186.                       ((dB>>6)<<(0))  ];
  187.             }
  188.         }
  189.         dst++;
  190.         src += srcbpp;
  191.         },
  192.         width);
  193.         src += srcskip;
  194.         dst += dstskip;
  195.     }
  196. }
  197.  
  198. /* fast RGB888->(A)RGB888 blending with surface alpha */
  199. static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info)
  200. {
  201.     int width = info->d_width;
  202.     int height = info->d_height;
  203.     Uint32 *srcp = (Uint32 *)info->s_pixels;
  204.     int srcskip = info->s_skip >> 2;
  205.     Uint32 *dstp = (Uint32 *)info->d_pixels;
  206.     int dstskip = info->d_skip >> 2;
  207.     SDL_PixelFormat *srcfmt = info->src;
  208.     unsigned alpha = srcfmt->alpha;
  209.  
  210.     while(height--) {
  211.         DUFFS_LOOP4({
  212.         Uint32 s;
  213.         Uint32 d;
  214.         Uint32 s1;
  215.         Uint32 d1;
  216.         s = *srcp;
  217.         d = *dstp;
  218.         s1 = s & 0xff00ff;
  219.         d1 = d & 0xff00ff;
  220.         d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
  221.         s &= 0xff00;
  222.         d &= 0xff00;
  223.         d = (d + ((s - d) * alpha >> 8)) & 0xff00;
  224.         *dstp = d1 | d | 0xff000000;
  225.         ++srcp;
  226.         ++dstp;
  227.         }, width);
  228.         srcp += srcskip;
  229.         dstp += dstskip;
  230.     }
  231. }
  232.  
  233. /* fast ARGB888->(A)RGB888 blending with pixel alpha */
  234. static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info)
  235. {
  236.     int width = info->d_width;
  237.     int height = info->d_height;
  238.     Uint32 *srcp = (Uint32 *)info->s_pixels;
  239.     int srcskip = info->s_skip >> 2;
  240.     Uint32 *dstp = (Uint32 *)info->d_pixels;
  241.     int dstskip = info->d_skip >> 2;
  242.  
  243.     while(height--) {
  244.         DUFFS_LOOP4({
  245.         Uint32 dalpha;
  246.         Uint32 d;
  247.         Uint32 s1;
  248.         Uint32 d1;
  249.         Uint32 s = *srcp;
  250.         Uint32 alpha = s >> 24;
  251.         /* FIXME: Here we special-case opaque alpha since the
  252.            compositioning used (>>8 instead of /255) doesn't handle
  253.            it correctly. Also special-case alpha=0 for speed?
  254.            Benchmark this! */
  255.         if(alpha == SDL_ALPHA_OPAQUE) {
  256.             *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000);
  257.         } else {
  258.             /*
  259.              * take out the middle component (green), and process
  260.              * the other two in parallel. One multiply less.
  261.              */
  262.             d = *dstp;
  263.             dalpha = d & 0xff000000;
  264.             s1 = s & 0xff00ff;
  265.             d1 = d & 0xff00ff;
  266.             d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
  267.             s &= 0xff00;
  268.             d &= 0xff00;
  269.             d = (d + ((s - d) * alpha >> 8)) & 0xff00;
  270.             *dstp = d1 | d | dalpha;
  271.         }
  272.         ++srcp;
  273.         ++dstp;
  274.         }, width);
  275.         srcp += srcskip;
  276.         dstp += dstskip;
  277.     }
  278. }
  279.  
  280. /* fast RGB565->RGB565 blending with surface alpha */
  281. static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info)
  282. {
  283.     int width = info->d_width;
  284.     int height = info->d_height;
  285.     Uint16 *srcp = (Uint16 *)info->s_pixels;
  286.     int srcskip = info->s_skip >> 1;
  287.     Uint16 *dstp = (Uint16 *)info->d_pixels;
  288.     int dstskip = info->d_skip >> 1;
  289.     unsigned alpha = info->src->alpha >> 3; /* downscale alpha to 5 bits */
  290.  
  291.     while(height--) {
  292.         DUFFS_LOOP4({
  293.         Uint32 s = *srcp++;
  294.         Uint32 d = *dstp;
  295.         /*
  296.          * shift out the middle component (green) to the high 16
  297.          * bits, and process all three RGB components at the same
  298.          * time.
  299.          */
  300.         s = (s | s << 16) & 0x07e0f81f;
  301.         d = (d | d << 16) & 0x07e0f81f;
  302.         d += (s - d) * alpha >> 5;
  303.         d &= 0x07e0f81f;
  304.         *dstp++ = d | d >> 16;
  305.         }, width);
  306.         srcp += srcskip;
  307.         dstp += dstskip;
  308.     }
  309. }
  310.  
  311. /* fast RGB555->RGB555 blending with surface alpha */
  312. static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info)
  313. {
  314.     int width = info->d_width;
  315.     int height = info->d_height;
  316.     Uint16 *srcp = (Uint16 *)info->s_pixels;
  317.     int srcskip = info->s_skip >> 1;
  318.     Uint16 *dstp = (Uint16 *)info->d_pixels;
  319.     int dstskip = info->d_skip >> 1;
  320.     unsigned alpha = info->src->alpha >> 3; /* downscale alpha to 5 bits */
  321.  
  322.     while(height--) {
  323.         DUFFS_LOOP4({
  324.         Uint32 s = *srcp++;
  325.         Uint32 d = *dstp;
  326.         /*
  327.          * shift out the middle component (green) to the high 16
  328.          * bits, and process all three RGB components at the same
  329.          * time.
  330.          */
  331.         s = (s | s << 16) & 0x03e07c1f;
  332.         d = (d | d << 16) & 0x03e07c1f;
  333.         d += (s - d) * alpha >> 5;
  334.         d &= 0x03e07c1f;
  335.         *dstp++ = d | d >> 16;
  336.         }, width);
  337.         srcp += srcskip;
  338.         dstp += dstskip;
  339.     }
  340. }
  341.  
  342. /* fast ARGB8888->RGB565 blending with pixel alpha */
  343. static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info)
  344. {
  345.     int width = info->d_width;
  346.     int height = info->d_height;
  347.     Uint32 *srcp = (Uint32 *)info->s_pixels;
  348.     int srcskip = info->s_skip >> 2;
  349.     Uint16 *dstp = (Uint16 *)info->d_pixels;
  350.     int dstskip = info->d_skip >> 1;
  351.  
  352.     while(height--) {
  353.         DUFFS_LOOP4({
  354.         Uint32 s = *srcp;
  355.         unsigned alpha = s >> 27; /* downscale alpha to 5 bits */
  356.         /* FIXME: Here we special-case opaque alpha since the
  357.            compositioning used (>>8 instead of /255) doesn't handle
  358.            it correctly. Also special-case alpha=0 for speed?
  359.            Benchmark this! */
  360.         if(alpha == (SDL_ALPHA_OPAQUE >> 3)) {
  361.             *dstp = (s >> 8 & 0xf800) + (s >> 5 & 0x7e0)
  362.               + (s >> 3  & 0x1f);
  363.         } else {
  364.             Uint32 d = *dstp;
  365.             /*
  366.              * convert source and destination to G0RAB65565
  367.              * and blend all components at the same time
  368.              */
  369.             s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
  370.               + (s >> 3 & 0x1f);
  371.             d = (d | d << 16) & 0x07e0f81f;
  372.             d += (s - d) * alpha >> 5;
  373.             d &= 0x07e0f81f;
  374.             *dstp = d | d >> 16;
  375.         }
  376.         srcp++;
  377.         dstp++;
  378.         }, width);
  379.         srcp += srcskip;
  380.         dstp += dstskip;
  381.     }
  382. }
  383.  
  384. /* fast ARGB8888->RGB555 blending with pixel alpha */
  385. static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info)
  386. {
  387.     int width = info->d_width;
  388.     int height = info->d_height;
  389.     Uint32 *srcp = (Uint32 *)info->s_pixels;
  390.     int srcskip = info->s_skip >> 2;
  391.     Uint16 *dstp = (Uint16 *)info->d_pixels;
  392.     int dstskip = info->d_skip >> 1;
  393.  
  394.     while(height--) {
  395.         DUFFS_LOOP4({
  396.         unsigned alpha;
  397.         Uint32 s = *srcp;
  398.         alpha = s >> 27; /* downscale alpha to 5 bits */
  399.         /* FIXME: Here we special-case opaque alpha since the
  400.            compositioning used (>>8 instead of /255) doesn't handle
  401.            it correctly. Also special-case alpha=0 for speed?
  402.            Benchmark this! */
  403.         if(alpha == (SDL_ALPHA_OPAQUE >> 3)) {
  404.             *dstp = (s >> 9 & 0x7c00) + (s >> 6 & 0x3e0)
  405.               + (s >> 3  & 0x1f);
  406.         } else {
  407.             Uint32 d = *dstp;
  408.             /*
  409.              * convert source and destination to G0RAB65565
  410.              * and blend all components at the same time
  411.              */
  412.             s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00)
  413.               + (s >> 3 & 0x1f);
  414.             d = (d | d << 16) & 0x03e07c1f;
  415.             d += (s - d) * alpha >> 5;
  416.             d &= 0x03e07c1f;
  417.             *dstp = d | d >> 16;
  418.         }
  419.         srcp++;
  420.         dstp++;
  421.         }, width);
  422.         srcp += srcskip;
  423.         dstp += dstskip;
  424.     }
  425. }
  426.  
  427. /* General (slow) N->N blending with per-surface alpha */
  428. static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info)
  429. {
  430.     int width = info->d_width;
  431.     int height = info->d_height;
  432.     Uint8 *src = info->s_pixels;
  433.     int srcskip = info->s_skip;
  434.     Uint8 *dst = info->d_pixels;
  435.     int dstskip = info->d_skip;
  436.     SDL_PixelFormat *srcfmt = info->src;
  437.     SDL_PixelFormat *dstfmt = info->dst;
  438.     int srcbpp = srcfmt->BytesPerPixel;
  439.     int dstbpp = dstfmt->BytesPerPixel;
  440.     unsigned sA = srcfmt->alpha;
  441.     unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
  442.  
  443.     while ( height-- ) {
  444.         DUFFS_LOOP4(
  445.         {
  446.         Uint32 pixel;
  447.         unsigned sR;
  448.         unsigned sG;
  449.         unsigned sB;
  450.         unsigned dR;
  451.         unsigned dG;
  452.         unsigned dB;
  453.         DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB);
  454.         DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB);
  455.         ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
  456.         ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
  457.         src += srcbpp;
  458.         dst += dstbpp;
  459.         },
  460.         width);
  461.         src += srcskip;
  462.         dst += dstskip;
  463.     }
  464. }
  465.  
  466. /* General (slow) colorkeyed N->N blending with per-surface alpha */
  467. static void BlitNtoNSurfaceAlphaKey(SDL_BlitInfo *info)
  468. {
  469.     int width = info->d_width;
  470.     int height = info->d_height;
  471.     Uint8 *src = info->s_pixels;
  472.     int srcskip = info->s_skip;
  473.     Uint8 *dst = info->d_pixels;
  474.     int dstskip = info->d_skip;
  475.     SDL_PixelFormat *srcfmt = info->src;
  476.     SDL_PixelFormat *dstfmt = info->dst;
  477.     Uint32 ckey = srcfmt->colorkey;
  478.     int srcbpp = srcfmt->BytesPerPixel;
  479.     int dstbpp = dstfmt->BytesPerPixel;
  480.     unsigned sA = srcfmt->alpha;
  481.     unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
  482.  
  483.     while ( height-- ) {
  484.         DUFFS_LOOP4(
  485.         {
  486.         Uint32 pixel;
  487.         unsigned sR;
  488.         unsigned sG;
  489.         unsigned sB;
  490.         unsigned dR;
  491.         unsigned dG;
  492.         unsigned dB;
  493.         RETRIEVE_RGB_PIXEL(src, srcbpp, pixel);
  494.         if(pixel != ckey) {
  495.             RGB_FROM_PIXEL(pixel, srcfmt, sR, sG, sB);
  496.             DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB);
  497.             ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
  498.             ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
  499.         }
  500.         src += srcbpp;
  501.         dst += dstbpp;
  502.         },
  503.         width);
  504.         src += srcskip;
  505.         dst += dstskip;
  506.     }
  507. }
  508.  
  509. /* General (slow) N->N blending with pixel alpha */
  510. static void BlitNtoNPixelAlpha(SDL_BlitInfo *info)
  511. {
  512.     int width = info->d_width;
  513.     int height = info->d_height;
  514.     Uint8 *src = info->s_pixels;
  515.     int srcskip = info->s_skip;
  516.     Uint8 *dst = info->d_pixels;
  517.     int dstskip = info->d_skip;
  518.     SDL_PixelFormat *srcfmt = info->src;
  519.     SDL_PixelFormat *dstfmt = info->dst;
  520.  
  521.     int  srcbpp;
  522.     int  dstbpp;
  523.  
  524.     /* Set up some basic variables */
  525.     srcbpp = srcfmt->BytesPerPixel;
  526.     dstbpp = dstfmt->BytesPerPixel;
  527.  
  528.     /* FIXME: for 8bpp source alpha, this doesn't get opaque values
  529.        quite right. for <8bpp source alpha, it gets them very wrong
  530.        (check all macros!)
  531.        It is unclear whether there is a good general solution that doesn't
  532.        need a branch (or a divide). */
  533.     while ( height-- ) {
  534.         DUFFS_LOOP4(
  535.         {
  536.         Uint32 pixel;
  537.         unsigned sR;
  538.         unsigned sG;
  539.         unsigned sB;
  540.         unsigned dR;
  541.         unsigned dG;
  542.         unsigned dB;
  543.         unsigned sA;
  544.         unsigned dA;
  545.         DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA);
  546.         DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
  547.         ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
  548.         ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
  549.         src += srcbpp;
  550.         dst += dstbpp;
  551.         },
  552.         width);
  553.         src += srcskip;
  554.         dst += dstskip;
  555.     }
  556. }
  557.  
  558.  
  559. SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index)
  560. {
  561.     SDL_PixelFormat *sf = surface->format;
  562.     SDL_PixelFormat *df = surface->map->dst->format;
  563.  
  564.     if(sf->Amask == 0) {
  565.     if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
  566.         if(df->BytesPerPixel == 1)
  567.         return BlitNto1SurfaceAlphaKey;
  568.         else
  569.         return BlitNtoNSurfaceAlphaKey;
  570.     } else {
  571.         /* Per-surface alpha blits */
  572.         switch(df->BytesPerPixel) {
  573.         case 1:
  574.         return BlitNto1SurfaceAlpha;
  575.  
  576.         case 2:
  577.         if(surface->map->identity) {
  578.             if(df->Gmask == 0x7e0)
  579.             return Blit565to565SurfaceAlpha;
  580.             else if(df->Gmask == 0x3e0)
  581.             return Blit555to555SurfaceAlpha;
  582.         }
  583.         return BlitNtoNSurfaceAlpha;
  584.  
  585.         case 4:
  586.         if(sf->Rmask == df->Rmask
  587.            && sf->Gmask == df->Gmask
  588.            && sf->Bmask == df->Bmask
  589.            && (sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff
  590.            && sf->BytesPerPixel == 4)
  591.             return BlitRGBtoRGBSurfaceAlpha;
  592.         else
  593.             return BlitNtoNSurfaceAlpha;
  594.  
  595.         case 3:
  596.         default:
  597.         return BlitNtoNSurfaceAlpha;
  598.         }
  599.     }
  600.     } else {
  601.     /* Per-pixel alpha blits */
  602.     switch(df->BytesPerPixel) {
  603.     case 1:
  604.         return BlitNto1PixelAlpha;
  605.  
  606.     case 2:
  607.         if(sf->BytesPerPixel == 4 && sf->Amask == 0xff000000
  608.            && sf->Gmask == 0xff00
  609.            && ((sf->Rmask == 0xff && df->Rmask == 0x1f)
  610.            || (sf->Bmask == 0xff && df->Bmask == 0x1f))) {
  611.         if(df->Gmask == 0x7e0)
  612.             return BlitARGBto565PixelAlpha;
  613.         else if(df->Gmask == 0x3e0)
  614.             return BlitARGBto555PixelAlpha;
  615.         }
  616.         return BlitNtoNPixelAlpha;
  617.  
  618.     case 4:
  619.         if(sf->Amask == 0xff000000
  620.            && sf->Rmask == df->Rmask
  621.            && sf->Gmask == df->Gmask
  622.            && sf->Bmask == df->Bmask
  623.            && sf->BytesPerPixel == 4)
  624.         return BlitRGBtoRGBPixelAlpha;
  625.         return BlitNtoNPixelAlpha;
  626.  
  627.     case 3:
  628.     default:
  629.         return BlitNtoNPixelAlpha;
  630.     }
  631.     }
  632. }
  633.  
  634.